package gui.customizer.panes.netfilter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import net.SSHConnectionProxy;
import net.miginfocom.swing.MigLayout;
import core.models.FilterRule;
import core.models.FlushRule;
import core.models.RuleSet;

public class PacketFilter extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2070373777355268271L;
	private DefaultFilterPolicyPanel defaultPolicyPanel;
	private JList listRules;
	private FilterRuleEditor filterRuleEditor;
	private JButton btnAdd;
	private JButton btnDelete;
	private SaveAndSend saveAndSend;

	public PacketFilter() {
		setLayout(new MigLayout("", "[][grow][]", "[][][][grow][grow]"));

		// Default Policy Panel
		defaultPolicyPanel = new DefaultFilterPolicyPanel();
		add(defaultPolicyPanel, "cell 0 0,grow");
		
		// Save and send Panel
		saveAndSend = new SaveAndSend();
		add(saveAndSend, "cell 1 0 2 1,grow");

		// List and buttons
		listRules = new JList();
		listRules.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listRules.setLayoutOrientation(JList.VERTICAL);

		JScrollPane listScroller = new JScrollPane(listRules);
		listScroller
				.setBorder(BorderFactory.createTitledBorder("Filter Rules"));
		add(listScroller, "cell 0 1 2 3,grow");

		btnAdd = new JButton("Add");
		add(btnAdd, "cell 2 1,growx");

		btnDelete = new JButton("Delete");
		add(btnDelete, "cell 2 2,growx");

		// Filter Rule Editor
		filterRuleEditor = new FilterRuleEditor();
		JScrollPane filterRuleEditorScroller = new JScrollPane(filterRuleEditor);
		filterRuleEditorScroller.setBorder(BorderFactory
				.createTitledBorder("Filter Rule Editor"));
		add(filterRuleEditorScroller, "cell 0 4 3 1,grow");

		// Initialize fields
		try {
			initialize();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void initialize() throws IOException {
		// Getting rules
		final RuleSet rs = new RuleSet();
		rs.loadRemoteRules("filter");

		// Policies combo boxes
		defaultPolicyPanel.setAvailablePolicies(FilterRule.getPolicies());
		defaultPolicyPanel.setPolicies(rs.getPolicyRuleSet());

		// List
		listRules.setModel(rs);
		listRules.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				if (arg0.getValueIsAdjusting())
					return;
				JList list = (JList) arg0.getSource();
				FilterRule selectedRule = (FilterRule) list.getSelectedValue();
				if (selectedRule != null)
					filterRuleEditor.setRule(selectedRule);
				else
					filterRuleEditor.hideApplyButton();
			}
		});
		
		// Buttons
		btnAdd.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				FilterRule rule = filterRuleEditor.getRule();
				rs.addElement(rule);
				listRules.setSelectedValue(rule, true);
			}
		});
		
		btnDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (listRules.getSelectedIndex() != -1) {
					int index = listRules.getSelectedIndex();
					rs.remove(index);
					if (index == rs.getSize())
						index--;
					listRules.setSelectedIndex(index);
				}
			}
		});
		
		filterRuleEditor.addListenerToApplyButton(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int index = listRules.getSelectedIndex();
				if (index != -1) {
					FilterRule newRule = filterRuleEditor.getRule();
					rs.remove(index);
					rs.add(index, newRule);
					listRules.setSelectedValue(newRule, true);
				}
			}
		});
		
		saveAndSend.addListenerToSendButton(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (!SSHConnectionProxy.isConnected())
					return;
				if (saveAndSend.ShouldAddFlushRules()) {
					FlushRule flush = new FlushRule("-F", "filter");
					rs.getFlushRuleSet().add(flush);
				}
				rs.setPolicyRuleSet(defaultPolicyPanel.getPolicies());
				try {
					rs.sendRules("filter");
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
	}
}
